package com.xsky.logic.tabcase;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Calendar;
import java.util.List;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;

import com.xsky.common.util.PageInfo;
import com.xsky.common.util.UUIDUtil;
import com.xsky.common.util.XMLConverter;
import com.xsky.database.dao.impl.BaseEntityDaoImpl;
import com.xsky.logic.casedesc.CaseDescLogic;
import com.xsky.logic.caseevent.CaseEventDescLogic;
import com.xsky.logic.caseresolve.CaseResolveDescLogic;
import com.xsky.operation.vo.TabCase;
import com.xsky.operation.vo.TabCaseDescResolve;
import com.xsky.operation.vo.TabCaseDispatch;
import com.xsky.operation.vo.TabCaseEventDesc;
import com.xsky.operation.vo.TabCaseResolveDesc;

public class CaseLogic {

	BaseEntityDaoImpl dao = new BaseEntityDaoImpl();

	public String queryCaseAndResolves(String caseId) {
		// 判断有多少条记录
		List<TabCaseDescResolve> caseDescResolves = new CaseDescLogic().queryByCaseId(caseId);

		CaseEventDescLogic cedLogic = new CaseEventDescLogic();
		CaseResolveDescLogic crdLogic = new CaseResolveDescLogic();
		DescResolveAll drAll = new DescResolveAll();
		if (caseDescResolves != null) {
			for (TabCaseDescResolve cdr : caseDescResolves) {

				List<TabCaseEventDesc> cedList = cedLogic.queryByCaseDescResolveId(cdr.getId());
				List<TabCaseResolveDesc> crdList = crdLogic.queryByCaseDescResolveId(cdr.getId());

				DescResovle dr = new DescResovle();
				dr.setCdr(cdr);
				dr.setCedList(cedList);
				dr.setCrdList(crdList);

				drAll.add(dr);
			}
		}

		return XMLConverter.convertToXML(drAll);
	}

	/**
	 * 与queryCaseAndResolves解析过程刚好相反
	 * 
	 * @param xml
	 * @return
	 */
	public String addOrUploadCaseDescAndResolves(String xml) {
		DescResolveAll drAll = XMLConverter.convertToObject(xml, DescResolveAll.class);
		if (drAll != null) {
			for (DescResovle dr : drAll.getDrList()) {
				addDescResovle(dr);
			}
		}
		return "<data><result>ok</result><uuid></uuid><info>保存【事件和解决描述】成功</info></data>";
	}

	private void addDescResovle(DescResovle dr) {
		new CaseDescLogic().addOrUpdate(dr.getCdr());
		if (dr.getCedList() != null) {
			for (TabCaseEventDesc ced : dr.getCedList()) {
				new CaseEventDescLogic().addOrUpdate(ced);
			}
		}
		if (dr.getCrdList() != null) {
			for (TabCaseResolveDesc crd : dr.getCrdList()) {
				new CaseResolveDescLogic().addOrUpdate(crd);
			}
		}
	}

	public String addOrUpdateDispatch(String xml) {
		TabCaseDispatch entity = XMLConverter.convertToObject(xml, TabCaseDispatch.class);
		if (StringUtils.isEmpty(entity.getId())) {
			entity.setId(UUIDUtil.getUUID());
		}
		dao.saveOrUpdateEntity(entity);
		return "<data><result>ok</result><uuid>" + entity.getId() + "</uuid><info>添加成功</info></data>";

	}

	public String addOrUpdateCase(String xml) {
		TabCase entity = XMLConverter.convertToObject(xml, TabCase.class);
		if (StringUtils.isEmpty(entity.getId())) {
			entity.setId(UUIDUtil.getUUID());
		}
		dao.saveOrUpdateEntity(entity);
		return "<data><result>ok</result><uuid>" + entity.getId() + "</uuid><info>添加成功</info></data>";

	}

	public String queryAllCase() {
		List<TabCase> list = dao.findAll(TabCase.class.getSimpleName());
		if (list == null) {
			return null;
		}

		return XMLConverter.convertToXML(list);
	}

	public String queryCaseDispatch(String caseId) {
		return XMLConverter.convertToXML(dao.findByKey(new TabCaseDispatch(), "caseId", caseId));
	}

	public String queryCaseById(String caseId){
		Object obj = dao.findByPrimaryKey(TabCase.class, "id", caseId);
		return XMLConverter.convertToXML(obj);
	}
	public String queryCase(String xml) {

		// <data>
		// <item>
		// <billNo></billNo>
		// <clientNo></clientNo>
		// <clientRealname></clientRealname>
		// <clientEmail></clientEmail>
		// <clientPhone></clientPhone
		// <clientCorpName></clientCorpName>
		// <clientDeptName>4</clientDeptName></data>
		// <engineerJn></engineerJn>
		// <engineerRealname></engineerRealname>
		// ...
		// </item>// item内的这些字段都以TabCase类的字段处理。该xml可以包含所有的TabCase的字段

		// <pageInfo>
		// <numberPerPage></numberPerPage>
		// <pageNumber></pageNumber>
		// <orderby></orderby>
		// <orderType></orderType>
		// </pageInfo>
		try {
			TabCase tabCase = XMLConverter.convertToObject(xml, TabCase.class);
			Document document = DocumentHelper.parseText(xml);
			String pageInfoXml = document.selectSingleNode("//data//pageInfo").asXML();
			PageInfo pageInfo = XMLConverter.convertToPageInfo(pageInfoXml);

			PropertyDescriptor[] pds = PropertyUtils.getPropertyDescriptors(TabCase.class);
			StringBuilder sb = new StringBuilder();
			sb.append(" 1 = 1 ");
			for (PropertyDescriptor pd : pds) {
				String name = pd.getName();
				Object value = PropertyUtils.getProperty(tabCase, pd.getName());
				if (value!=null&&StringUtils.isNotBlank(value.toString()) && !name.equals("class")) {
					sb.append(" and "+name + " = '" + value.toString()+"'");
				}
			}
			
			System.out.println(sb);
			
			List list = dao.fetchByPagesWithCondition(TabCase.class.getSimpleName(), pageInfo.getStart() + "", pageInfo
					.getNumberPerPage()
					+ "", sb.toString(), pageInfo.getOrderby(), pageInfo.getOrderType());
			return XMLConverter.convertToXML(list);

		} catch (DocumentException e) {
			e.printStackTrace();
		} catch(Exception ite){
			ite.printStackTrace();
		}
		return null;
	}

	private int getCount(int year, int month) {
		String monthStr = month > 9 ? month + "" : "0" + month;
		int nextMonth = month + 1;
		String nextMonthStr = nextMonth > 9 ? nextMonth + "" : "0" + nextMonth;
		String fromTime = year + "-" + monthStr + "-00";
		String toTime = year + "-" + nextMonthStr + "-00";

		return getCaseCount(fromTime, toTime);
	}

	private int getCaseCount(String fromTime, String toTime) {
		String hql = "  createTime > '" + fromTime + "'";
		hql += " and createTime < '" + toTime + "'";
		return dao.fetchCount(TabCase.class.getName(), hql);
	}

	int getCaseNumOfPremonth() {
		Calendar cal = Calendar.getInstance();
		int year = cal.get(Calendar.YEAR);
		int premonth = cal.get(Calendar.MONTH);

		return getCount(year, premonth);
	}

	int getCaseNumOfCurmonth() {
		Calendar cal = Calendar.getInstance();
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH) + 1;

		return getCount(year, month);
	}

	int getUnclosedCaseNum() {
		String hql = " status!= " + Status.CLOSED;
		return dao.fetchCount(TabCase.class.getName(), hql);
	}

	int getCaseNumOfCurWeek() {
		Calendar cal = Calendar.getInstance();
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH) + 1;
		int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);

		int day = cal.get(Calendar.DAY_OF_WEEK);
		// 本周到目前为止过了几天（不包含当天），如果周一，则为0，周日则为6
		int dayNum = 1;
		if (day == Calendar.SUNDAY) {
			dayNum = 6;
		} else {
			dayNum = day - 2;
		}
		// 跳到本周一
		cal.add(Calendar.DAY_OF_MONTH, -dayNum);
		// 开始日期： 本周一的0点0分
		String fromTime = toDateStr(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH));
		// 结束日期： 明天的0点0分。
		String toTime = toDateStr(year, month, dayOfMonth + 1);
		String hql = " createTime < '" + toTime + "'";
		hql += " and createTime > '" + fromTime + "'";

		return dao.fetchCount(TabCase.class.getName(), hql);

	}

	String toDateStr(int year, int month, int dayOfMonth) {
		String monthStr = month > 9 ? month + "" : "0" + month;
		return year + "-" + monthStr + "-" + dayOfMonth;
	}

	public String getStatInfo() {
		StringBuilder sb = new StringBuilder();
		sb.append("<data>");
		sb.append("<preMonth>" + getCaseNumOfPremonth() + "</preMonth>");
		sb.append("<currentMonth>" + getCaseNumOfPremonth() + "</currentMonth>");
		sb.append("<currentWeek>" + getCaseNumOfCurWeek() + "</currentWeek>");
		sb.append("<unclosed>" + getUnclosedCaseNum() + "</unclosed>");
		sb.append("</data>");
		return sb.toString();
	}

}
